﻿using System;
using System.Collections.Generic;

namespace Jacobi.ComponentModel.Decomposition
{
    /// <summary>
    /// The IOperation interface is the base interface of a filter.
    /// </summary>
    public interface IOperation
    {
        /// <summary>
        /// Processes one data item from the pipe.
        /// </summary>
        /// <remarks>The engine will call the Process method repeatedly.</remarks>
        void Process();
    }

    /// <summary>
    /// This interface defines the connections a filter has with other filters through pipes and ports.
    /// </summary>
    /// <typeparam name="Tin">The data type of the incoming data items.</typeparam>
    /// <typeparam name="Tout">The data type of the outgoing data items.</typeparam>
    public interface IFilter<Tin, Tout> : IOperation
    {
        /// <summary>
        /// Gets a list of Pipe consumer ports that are used to process data from.
        /// </summary>
        IList<IConsumerPort<Tin>> Inputs { get; }

        /// <summary>
        /// Gets a list of Pipe provider ports that are used to output processed data to.
        /// </summary>
        IList<IProducerPort<Tout>> Outputs { get; }
    }

    /// <summary>
    /// An optional interface a filter can implement to publish its connection requirements and latency.
    /// </summary>
    public interface IFilterInfo
    {
        /// <summary>
        /// Gets the minimal number of inputs the filter requires.
        /// </summary>
        int MinInputCount { get; }
        /// <summary>
        /// Gets the maximal number of inputs the filter can handle.
        /// </summary>
        int MaxInputCount { get; }

        /// <summary>
        /// Gets the minimal number of outputs the filter requers
        /// </summary>
        int MinOutputCount { get; }
        /// <summary>
        /// Gets the maximal number of outputs the filter can handle.
        /// </summary>
        int MaxOutputCount { get; }

        /// <summary>
        /// Gets the processing latency in milliseconds.
        /// </summary>
        long Latency { get; }
    }
}
